/**
 * Copyright 2009 Henning Teek, Ingo Renner
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.bricket.web.common.brix.plugin.menuml;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.jcr.ReferentialIntegrityException;

import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;

import brix.BrixNodeModel;
import brix.jcr.api.JcrSession;
import brix.jcr.exception.JcrException;
import brix.jcr.wrapper.BrixNode;
import brix.web.generic.BrixGenericPanel;
import brix.web.util.AbstractModel;
import brix.workspace.Workspace;

import com.googlecode.bricket.web.common.brix.plugin.menuml.editor.MenuMultiLangEditor;

public class ManageMenuMultiLangPanel extends BrixGenericPanel<Workspace> {
	public ManageMenuMultiLangPanel(String id, final IModel<Workspace> model) {
		super(id, model);

		IModel<List<BrixNode>> listViewModel = new LoadableDetachableModel<List<BrixNode>>() {
			@Override
			protected List<BrixNode> load()
			{
				return MenuMultiLangPlugin.get().getMenuNodes(ManageMenuMultiLangPanel.this.getModelObject().getId());
			}
		};

		add(new MenuListView("listView", listViewModel));
		setupEditor();

		add(new Link<Object>("newMenu") {
			@Override
			public void onClick() {
				currentMenu = new MenuMultiLang();
				currentNode.setObject(null);
				setupEditor();
			}

			@Override
			public boolean isEnabled() {
				return currentNode.getObject() != null;
			}
		});
	}

	@Override
	protected void onBeforeRender() {
		String workspaceId = getModelObject().getId();
		BrixNode current = currentNode.getObject();
		if (current != null && current.getSession().getWorkspace().getName().equals(workspaceId) == false) {
			currentNode.setObject(null);
			currentMenu = new MenuMultiLang();
			setupEditor();
		}
		super.onBeforeRender();
	}

	private class MenuListView extends ListView<BrixNode> {
		public MenuListView(String id, IModel<List<BrixNode>> model) {
			super(id, model);
		}

		@Override
		protected void populateItem(final ListItem<BrixNode> item) {
			Link<Object> select = new Link<Object>("select") {
				@Override
				public void onClick() {
					onSelectLinkClicked(item.getModelObject());
				}

				@Override
				public boolean isEnabled() {
					return item.getModelObject().equals(currentNode.getObject()) != true;
				}
			};
			IModel<String> labelModel = new AbstractModel<String>() {
				@Override
				public String getObject() {
					BrixNode node = item.getModelObject();
					MenuMultiLang menu = new MenuMultiLang();
					menu.loadConfig(node);
					return menu.getName();
				}
			};
			select.add(new Label("label", labelModel));
			item.add(select);
		}

		@Override
		protected IModel<BrixNode> getListItemModel(IModel<? extends List<BrixNode>> listViewModel, int index) {
			List<BrixNode> nodes = listViewModel.getObject();
			return new BrixNodeModel(nodes.get(index));
		}
	};

	private void onSelectLinkClicked(BrixNode node) {
		currentNode.setObject(node);
		currentMenu = new MenuMultiLang();
		currentMenu.load(node);
		setupEditor();
	}

	private void setupEditor() {
		Component editor = new EditorPanel("editor", new PropertyModel<MenuMultiLang>(this, "currentMenu"));
		if (this.editor == null) {
			add(editor);
		}
		else {
			this.editor.replaceWith(editor);
		}
		this.editor = editor;
	}

	private class EditorPanel extends BrixGenericPanel<MenuMultiLang> {

		public EditorPanel(String id, final IModel<MenuMultiLang> model) {
			super(id, model);

			Form<MenuMultiLang> form = new Form<MenuMultiLang>("form", new CompoundPropertyModel<MenuMultiLang>(model));
			add(form);

			form.add(new TextField<String>("name").setRequired(true));

			form.add(getLangSelect("otherLocale"));
			
			form.add(new MenuMultiLangEditor("editor", model));

			form.add(new SubmitLink("save")	{
				@Override
				public void onSubmit()	{
					MenuMultiLangPlugin plugin = MenuMultiLangPlugin.get();
					currentNode.setObject(plugin.saveMenu(model.getObject(), ManageMenuMultiLangPanel.this.getModelObject()
							.getId(), currentNode.getObject()));
					getSession().info(ManageMenuMultiLangPanel.this.getString("menuSaved"));
				}
			});

			form.add(new SubmitLink("delete") {
				@Override
				public void onSubmit() {
					try	{
						JcrSession session = currentNode.getObject().getSession();
						currentNode.getObject().remove();
						session.save();

						currentNode.setObject(null);
						currentMenu = new MenuMultiLang();
						setupEditor();
					}
					catch (JcrException e)
					{
						if (e.getCause() instanceof ReferentialIntegrityException)
						{
							currentNode.getObject().getSession().refresh(false);
							currentNode.detach();
							getSession().error("Couldn't delete menu, it is referenced from a tile(s).");
						}
					}
				}

				@Override
				public boolean isVisible() {
					return currentNode.getObject() != null;
				}
			}.setDefaultFormProcessing(false));

			add(new FeedbackPanel("feedback"));
		}

		// Selectbox for locale of the other title field
		private Component getLangSelect(String id) {
	    	List<Locale> locales = new ArrayList<Locale>();
	    	for (Locale locale : Locale.getAvailableLocales()) {
	    		locales.add(locale);
			}
	    	DropDownChoice<Locale> ddc = new DropDownChoice<Locale>(id, locales, new ChoiceRenderer<Locale>());
	    	ddc.setNullValid(false);
	    	return ddc;
	    }
	};

	private Component editor;

	private IModel<BrixNode> currentNode = new BrixNodeModel();
	private MenuMultiLang currentMenu = new MenuMultiLang();

	@Override
	protected void onDetach()
	{
		currentNode.detach();
		currentMenu.detach();
		super.onDetach();
	}
}
